package com.hcj.example.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("test")
    public String test(){
        return "hello test OAuth2,this is not need to auth";
    }


    @RequestMapping("select")
    public String select(){
        SecurityContext context = SecurityContextHolder.getContext();
        return "hello test OAuth2: select " + "必须满足 #oauth2.hasScope('select') and hasAuthority('oauth2') 才能调通";
    }

    @RequestMapping("all")
    public String all(){
        return "hello test OAuth2: all ";
    }

    @RequestMapping("read")
    public String read(){
        return "hello test OAuth2: read ";
    }

    @RequestMapping("write")
    public String write(){
        return "hello test OAuth2: write ";
    }

    /**
     * 模拟来自客户端的请求
     * @return
     */
    @RequestMapping("mockTestFromClient")
    public String mockTestFromClient(){
        // 1. client授权获得access_token
        // 2. 拿access_token,请求资源
        long s = System.currentTimeMillis();
        String resStr = restTemplate.getForObject("http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client-id&client_secret=client-secret", String.class);
        JSONObject json = JSON.parseObject(resStr);
        long e1 = System.currentTimeMillis();
        log.info("client授权获得access_token:{}, 耗时：{}", json, e1-s);


        // 访问 test/select， 必须满足 #oauth2.hasScope('select') and hasAuthority('oauth2')
        // 例如 scope=select && authorities.contain("oauth2")
        String result = restTemplate.getForObject(String.format("http://localhost:8080/test/select?access_token=%s", json.getString("access_token")), String.class);
        long e2 = System.currentTimeMillis();
        log.info("拿access_token,请求资源:{}, 耗时：{}", result, e2-e1);


        // 访问 api/select,授权通过了就能访问
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        HttpHeaders header = new HttpHeaders();
        header.setContentType(MediaType.APPLICATION_JSON);
        header.add("Authorization", "Bearer "+ json.getString("access_token"));
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, header);
        String body = restTemplate.exchange("http://localhost:8080/api/select", HttpMethod.GET, httpEntity, String.class).getBody();
        long e3 = System.currentTimeMillis();
        log.info("再拿access_token,请求资源:{}, 耗时：{}", body, e3-e2);
        return result;
    }
}
